package com.kly.user.serviceImpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.api.Page;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.TimeUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.eventbus.AsyncEventBus;
import com.kly.enums.ParameterTypeEnum;
import com.kly.service.MemberService;
import com.kly.user.db.dao.*;
import com.kly.user.db.entity.*;
import com.kly.user.dto.*;
import com.kly.user.dto.chatter.request.ConversationOPReq;
import com.kly.user.dto.vo.TrafficSourceReq;
import com.kly.user.enums.*;
import com.kly.user.eventbus.ActionEnum;
import com.kly.user.eventbus.Event;
import com.kly.user.service.UserTrafficSourceService;
import com.kly.user.service.WhiteListService;
import com.kly.user.service.WlmService;
import com.kly.user.serviceImpl.traffic.homepage.HomepageTrafficHandler;
import com.kly.user.task.UserTaskConfig;
import com.kly.user.utils.ImagePrefixUtils;
import com.kly.user.utils.ServiceUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * Who like me 相关服务类
 *
 * @author linqu
 */
@Service("wlmService")
public class WlmServiceImpl implements WlmService {

    private static Log logger = LogFactory.getLog(WlmServiceImpl.class);

    @Resource
    UserDao userDao;
    @Resource
    UserWlmDao userWlmDao;
    @Resource
    UserWlmLogDao userWlmLogDao;
    @Resource
    UserAlbumsContentDao userAlbumsContentDao;
    @Resource
    UserProfileDao userProfileDao;
    @Resource
    UserInterestsDao userInterestsDao;
    @Resource
    UserConversationDao userConversationDao;
    @Resource
    AsyncEventBus asyncEventBus;
    @Resource
    UserUsageBenefitsDao usageBenefitsDao;
    @Resource
    UserTaskConfig userTaskConfig;
    @Resource
    AsyncEventBus pushEventBus;
    @Resource
    IssueUserDao issueUserDao;
    @Resource
    UserBehaviorGpsDao userBehaviorGpsDao;
    @Resource
    private UserTrafficSourceService userTrafficSourceService;

    @Resource
    private UserGreetingCommonContentDao userGreetingCommonContentDao;

    @Resource
    MemberService memberService;

    @Resource
    private WhiteListService whiteListService;

    @Resource
    CustomersDao customersDao;

    @Resource
    CustomersUserDao customersUserDao;

    @NacosValue(value = "${meboo.home.page.like.first.count:5}", autoRefreshed = true)
    private Integer mebooHomePageLikeFirstCount;

    @NacosValue(value = "${meboo.homepage.new.policy.version:5}", autoRefreshed = true)
    private Integer homepageNewPolicyVersion;

    // 流量池测试开关
    @NacosValue(value = "${issue.user.pool.test:false}", autoRefreshed = true)
    private boolean issueUserPoolTest;
    // 流量池测试用户
    @NacosValue(value = "${issue.user.pool.test.userCode}", autoRefreshed = true)
    private String issueUserPoolTestUserCode;

    @NacosValue(value = "${meboo.homepage.new.policy.show.detail:false}", autoRefreshed = true)
    private boolean showHomepageNewPolicyVersionDetail;

    @NacosValue(value = "${meboo.home.page.like.last.count:5}", autoRefreshed = true)
    private Integer mebooHomePageLikeLastCount;

    @NacosValue(value = "${meboo.home.page.conversation.count:10}", autoRefreshed = true)
    private Integer mebooHomePageConversationCount;

    @NacosValue(value = "${meboo.home.page.level.count:10}", autoRefreshed = true)
    private Integer mebooHomePageLevelCount;


    @NacosValue(value = "${flashChatLogicVersion:2}", autoRefreshed = true)
    private Integer flashChatLogicVersion;

    /**
     * 推荐用户列表
     *
     * @param userCode  用户码
     * @param recordNum 返回记录数
     * @return 返回推荐用户集合
     */
    @Override
    public Response<List<RecommendUserDto>> recommendUsers(String userCode, Integer recordNum) {

        // 获取用户信息
        final UserEntity currentUser = userDao.selectByUserCode(userCode);
        if (Objects.isNull(currentUser)) {
            logger.error("未查询到用户, userCode:{}", userCode);
            return Response.error(ResultStatus.USER_NOT_EXIST, "User not found, userCode:{}" + userCode);
        }

        // 判断是否为完成注册的用户
        if (Objects.nonNull(currentUser.getStatus()) && currentUser.getStatus() != UserStatus.ACTIVE.getType()) {
            logger.error("用户未完成注册或用户已注销, userCode:{}", userCode);
            return Response.error(ResultStatus.USER_REGISTRATION_NOT_COMPLETED, "User did not complete registration, userCode:{}" + userCode);
        }
        long start = System.currentTimeMillis();

        // 查询推荐的model（meboo-v3.1.3版本要求属于白名单的账户默认查询mode用户）
        final List<UserEntity> recommendModels = queryUsers(userCode, recordNum, currentUser.getLookingFor());

        logger.info("== recommendUsers.queryUsers ==,cost:{}", System.currentTimeMillis() - start);

        if (CollectionUtils.isEmpty(recommendModels)) {
            return Response.ok();
        }

        final List<String> modelUserCodes = recommendModels.stream().map(UserEntity::getUserCode).collect(Collectors.toList());

        // 查询model的兴趣
        final List<UserInterestsEntity> modelInterests = userInterestsDao.queryInterestsByUserCode(modelUserCodes);
        final Map<String, List<UserInterestsEntity>> interestsGroupByUserCode = modelInterests.parallelStream().collect(Collectors.groupingBy(UserInterestsEntity::getUserCode));
        logger.info("== recommendUsers.queryInterestsByUserCode ==,cost:{}", System.currentTimeMillis() - start);

        //查询经纬度信息
        final List<UserBehaviorGpsEntity> userBehaviorGpsEntities = userBehaviorGpsDao.queryGpsListByUserCode(modelUserCodes);
        final Map<String, List<UserBehaviorGpsEntity>> UserBehaviorGpsByUserCode = userBehaviorGpsEntities.parallelStream().collect(Collectors.groupingBy(UserBehaviorGpsEntity::getUserCode));


        // 查询model的个人照片
        final List<UserAlbumsContentEntity> modelPersonalPhotos = userAlbumsContentDao.queryImagesByAlbumTypes(modelUserCodes, Collections.singletonList(AlbumsType.PERSONAL_ALBUMS.getType()));
        final Map<String, List<UserAlbumsContentEntity>> photosGroupByUserCode = modelPersonalPhotos.parallelStream().collect(Collectors.groupingBy(UserAlbumsContentEntity::getUserCode));
        logger.info("== recommendUsers.queryImagesByAlbumType ==,cost:{}", System.currentTimeMillis() - start);

        //查询about me
        List<UserProfileEntity> list = userProfileDao.getList(modelUserCodes, 1);
        Map<String, String> userCodsAndAboutMe = new HashMap<>();
        list.forEach(p -> {
            userCodsAndAboutMe.put(p.getUserCode(), p.getAboutMe());
        });

        final Response<List<RecommendUserDto>> response = Response.ok(recommendModels.stream().map(model -> getRecommendUserDto(currentUser, model, interestsGroupByUserCode.get(model.getUserCode()), photosGroupByUserCode.get(model.getUserCode()), UserBehaviorGpsByUserCode.get(model.getUserCode()), userCodsAndAboutMe)).collect(Collectors.toList()));
        logger.info("== recommendUsers.getRecommendUserDto ==,cost:{}", System.currentTimeMillis() - start);
        return response;
    }

    /**
     * 是否走非自然流量策略
     * <p>
     * 【pp-v1.1.0】12. 流量侧-自然流量>>全局规则>>8. 过滤CM
     */
    private Integer getFilterUsertypeForRecommend(UserEntity currentUser) {
        TrafficSourceReq req = TrafficSourceReq.builder()
                .userCode(currentUser.getUserCode())
                .appCode(currentUser.getAppCode())
                .mobile(currentUser.getMobile())
                .email(currentUser.getEmail())
                .build();
        Response<TrafficSourceDto> resp = userTrafficSourceService.getTrafficSource(req);
        if (!resp.isSuccess() || resp.getData() == null) {
            return null;
        }

        if (AppCodeEnum.MEBOO.getAppCode().equals(currentUser.getAppCode()) && resp.getData().getWhiteFlag() == 1) {
            return UserType.MODEL.getType();
        }

        // 过滤CM 如果开关关闭，一律走非自然流量策略；如果开关开启，自然流量走自然流量策略
        if (TrafficSourceEnum.Organic.equals(resp.getData().getTrafficSourceEnum())) {
            return UserType.CHATTER_MODEL.getType();
        }

        return null;
    }


    /**
     * flash chate 推荐用户
     *
     * @param userCode
     * @param recordNum
     * @return
     */
    public Response<List<RecommendUserDto>> fcRecommendUsers(String userCode, Integer recordNum) {

        // 获取用户信息
        final UserEntity currentUser = userDao.selectByUserCode(userCode);
        if (Objects.isNull(currentUser)) {
            logger.error("未查询到用户, userCode:{}", userCode);
            return Response.error(ResultStatus.USER_NOT_EXIST, "User not found, userCode:{}" + userCode);
        }

        // 判断是否为完成注册的用户
        if (Objects.nonNull(currentUser.getStatus()) && currentUser.getStatus() != UserStatus.ACTIVE.getType()) {
            logger.error("用户未完成注册或用户已注销, userCode:{}", userCode);
            return Response.error(ResultStatus.USER_REGISTRATION_NOT_COMPLETED, "User did not complete registration, userCode:{}" + userCode);
        }
        long start = System.currentTimeMillis();

        // 查询推荐的model
        final List<UserEntity> recommendModels = queryUsers(userCode, recordNum, currentUser.getLookingFor());


        logger.info("== recommendUsers.queryUsers ==,cost:{}", System.currentTimeMillis() - start);

        if (CollectionUtils.isEmpty(recommendModels)) {
            return Response.ok();
        }

        final List<String> modelUserCodes = recommendModels.stream().map(UserEntity::getUserCode).collect(Collectors.toList());

        // 查询model的兴趣
        final List<UserInterestsEntity> modelInterests = userInterestsDao.queryInterestsByUserCode(modelUserCodes);
        final Map<String, List<UserInterestsEntity>> interestsGroupByUserCode = modelInterests.parallelStream().collect(Collectors.groupingBy(UserInterestsEntity::getUserCode));
        logger.info("== recommendUsers.queryInterestsByUserCode ==,cost:{}", System.currentTimeMillis() - start);


        // 查询model的个人照片
        final List<UserAlbumsContentEntity> modelPersonalPhotos = userAlbumsContentDao.queryImagesByAlbumTypes(modelUserCodes, Collections.singletonList(AlbumsType.PERSONAL_ALBUMS.getType()));
        final Map<String, List<UserAlbumsContentEntity>> photosGroupByUserCode = modelPersonalPhotos.parallelStream().collect(Collectors.groupingBy(UserAlbumsContentEntity::getUserCode));
        logger.info("== recommendUsers.queryImagesByAlbumType ==,cost:{}", System.currentTimeMillis() - start);

        //查询about me
        List<UserProfileEntity> list = userProfileDao.getList(modelUserCodes, 1);
        Map<String, String> userCodsAndAboutMe = new HashMap<>();
        list.forEach(p -> {
            userCodsAndAboutMe.put(p.getUserCode(), p.getAboutMe());
        });

        final Response<List<RecommendUserDto>> response = Response.ok(recommendModels.stream().map(model -> getRecommendUserDto(currentUser, model, interestsGroupByUserCode.get(model.getUserCode()), photosGroupByUserCode.get(model.getUserCode()), null, userCodsAndAboutMe)).collect(Collectors.toList()));
        logger.info("== recommendUsers.getRecommendUserDto ==,cost:{}", System.currentTimeMillis() - start);
        return response;
    }


    /**
     * 用户操作：1-喜欢 2-不喜欢
     *
     * @param userCode       用户码
     * @param friendUserCode 被评价的用户
     * @param likeOp
     * @return
     */
    @Override
    public Response doLike(String userCode, String friendUserCode, Integer likeOp) {
        return Response.ok();
    }

    /**
     * 用户操作：1-拉黑 2-取消拉黑 3-隐藏 4-举报
     *
     * @param userCode       用户码
     * @param friendUserCode 被操作的用户
     * @param opType
     * @param reason         操作理由
     * @return
     */
    @Override
    public Response doAction(String userCode, String friendUserCode, Integer opType, String reason) {
        return Response.ok();
    }

    @Override
    public Response<AddWlmUserDto> addWlmUser(AddWlmReq addWlmReq) {

        // 参数为空， 不作添加操作
        if (Objects.isNull(addWlmReq) || StringUtils.isEmpty(addWlmReq.getUserCode())) {
            return Response.ok();
        }

        // 当前用户likes model记录
        final List<UserWlmEntity> userList = getUserWlmEntities(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend());
        logger.info("==添加wlm记录 ==,我是否有和对方的记录:{},fromUserCode:{},toUserCode:{}", userList.size() > 0, addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend());

        // model用户likes当前用户记录
        final List<UserWlmEntity> modelList = getUserWlmEntities(addWlmReq.getUserCodeFriend(), addWlmReq.getUserCode());
        logger.info("==添加wlm记录 ==,对方是否有关于我的记录:{},fromUserCode:{},toUserCode:{}", userList.size() > 0, addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend());
        // 相互喜欢标识
        boolean matched = isMatched(addWlmReq, modelList);

        final int likeType = matched ? LikeEnum.LIKE_EACH_OTHER.getType() : addWlmReq.getLikeType();
        logger.info("==添加wlm记录 ==,我现在和对方的关系类型是:{}", likeType);

        final AddWlmUserDto addWlmUserDto = AddWlmUserDto.builder().build();
        UserWlmEntity wlmUser;

        if (CollectionUtils.isEmpty(userList)) {
            UserWlmEntity entity = addUserWlmEntity(addWlmReq, matched);
            BeanUtils.copyProperties(entity, addWlmUserDto);
            addWlmUserDto.setMatched(matched);
            wlmUser = entity;

            if (CollectionUtils.isNotEmpty(modelList)) {
                final UserWlmEntity model = modelList.get(0);

                if (matched) {
                    model.setContactTime(new Date());
                    model.setNewFlag(NewFlag.NEWS.getType());
                    model.setWlmType(likeType);
                    if (model.getConnectType() == 0) {
                        model.setConnectType(WLMType.WLM.getCode());
                    }
                    // 推送match消息到model端
//                    pushNewMatchMessage(model.getUserCodeWlm(), AppEnum.MECHAT);
                    userWlmDao.updateByPrimaryKey(model);

//                    final UserEntity modelUser = userDao.selectByUserCode(model.getUserCode());
//                    // 通知客户端进行chat list列表刷新
//                    pushMessage(model.getUserCode(), addWlmUserDto.getUserCode(), modelUser.getOnline(), addWlmReq.getFlashchatFlag(), "S20005");
//                    // 通知客户端进行new match列表刷新
//                    pushMessage(model.getUserCode(), addWlmUserDto.getUserCode(), modelUser.getOnline(), addWlmReq.getFlashchatFlag(), "S20006");

                } else {
                    model.setDislikeTime(new Date());
                    userWlmDao.updateByPrimaryKey(model);
                }
            }
        } else {
            wlmUser = userList.get(0);
            wlmUser.setWlmType(likeType);
            if (matched) {
                wlmUser.setContactTime(new Date());
                wlmUser.setLikesTime(new Date());
                wlmUser.setNewFlag(NewFlag.NEWS.getType());
                if (wlmUser.getConnectType() == 0) {
                    wlmUser.setConnectType(WLMType.WLM.getCode());
                }
            }
            userWlmDao.updateByPrimaryKey(wlmUser);

            if (CollectionUtils.isNotEmpty(modelList)) {
                final UserWlmEntity model = modelList.get(0);
                model.setContactTime(new Date());
                model.setNewFlag(NewFlag.NEWS.getType());
                model.setWlmType(likeType);
                if (matched) {
                    if (model.getConnectType() == 0) {
                        model.setConnectType(WLMType.WLM.getCode());
                    }
                    userWlmDao.updateByPrimaryKey(model);
                    final UserEntity modelUser = userDao.selectByUserCode(model.getUserCode());
                    // 通知客户端进行chat list列表刷新
                    pushMessage(model.getUserCode(), addWlmUserDto.getUserCode(), modelUser.getOnline(), addWlmReq.getFlashchatFlag(), "S20005");
                    // 通知客户端进行new match列表刷新
                    pushMessage(model.getUserCode(), addWlmUserDto.getUserCode(), modelUser.getOnline(), addWlmReq.getFlashchatFlag(), "S20006");
                }
                // 修补用户已经划卡后，流量又下发wlm，导致wlm列表无法dislike操作
                else if (likeType == LikeEnum.DO_NOT.getType()) {
                    model.setDislikeTime(new Date());
                    userWlmDao.updateByPrimaryKey(model);
                }

            }
        }

        BeanUtils.copyProperties(wlmUser, addWlmUserDto);
        addWlmUserDto.setMatched(matched);
        return Response.ok(addWlmUserDto);
    }

    private boolean isMatched(AddWlmReq addWlmReq, List<UserWlmEntity> modelList) {
        if (CollectionUtils.isEmpty(modelList)) {
            return Boolean.FALSE;
        }
        if (Objects.nonNull(addWlmReq.getLikeType()) && LikeEnum.LIKE.getType() == addWlmReq.getLikeType()) {
            Predicate<UserWlmEntity> matchedPredict = o -> LikeEnum.LIKE.getType() == o.getWlmType() || LikeEnum.LIKE_EACH_OTHER.getType() == o.getWlmType();

            return modelList.stream().anyMatch(matchedPredict);
        }
        return Boolean.FALSE;
    }

    @Override
    public Response<AddWlmUserDto> connectByFlashChat(AddWlmReq addWlmReq) {

        if (flashChatLogicVersion == 2) {
            connectByFlashChatV2(addWlmReq);
            return Response.ok();
        }

        final UserEntity userInfo = userDao.selectByUserCode(addWlmReq.getUserCode());
        if (UserType.CHATTER_MODEL.getType() == userInfo.getUserType()) {
            final List<UserWlmEntity> modelLikeRecord = userWlmDao.queryConnectRecord(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend());
            if (CollectionUtils.isEmpty(modelLikeRecord)) {
                UserWlmEntity entity = new UserWlmEntity();
                entity.setUserCode(addWlmReq.getUserCode()).setUserCodeWlm(addWlmReq.getUserCodeFriend()).setWlmType(LikeEnum.LIKE_EACH_OTHER.getType()).setContactTime(new Date()).setConnectType(WLMType.CHATTERFLASHCHAT.getCode());
                userWlmDao.insert(entity);
            }

            final List<UserWlmEntity> userLikeRecord = userWlmDao.queryConnectRecord(addWlmReq.getUserCodeFriend(), addWlmReq.getUserCode());
            if (CollectionUtils.isEmpty(userLikeRecord)) {
                UserWlmEntity entity = new UserWlmEntity();
                entity.setUserCode(addWlmReq.getUserCodeFriend()).setUserCodeWlm(addWlmReq.getUserCode()).setWlmType(LikeEnum.LIKE_EACH_OTHER.getType()).setContactTime(new Date()).setConnectType(WLMType.CHATTERFLASHCHAT.getCode());
                if (addWlmReq.getFlashchatFlag()) {
                    entity.setFlashchatTime(new Date());
                    entity.setFlashchatFlag(Boolean.TRUE);
                    entity.setConnectType(WLMType.CHATTERFLASHCHAT.getCode());

                }
                userWlmDao.insert(entity);
            } else {
                final UserWlmEntity existsUserLikeRecord = userLikeRecord.get(0);
                existsUserLikeRecord.setWlmType(LikeEnum.LIKE_EACH_OTHER.getType());
                existsUserLikeRecord.setContactTime(new Date());
                if (addWlmReq.getFlashchatFlag()) {
                    existsUserLikeRecord.setFlashchatTime(new Date());
                    existsUserLikeRecord.setFlashchatFlag(Boolean.TRUE);
                    if (existsUserLikeRecord.getConnectType() == 0) {
                        existsUserLikeRecord.setConnectType(WLMType.CHATTERFLASHCHAT.getCode());
                    }
                }
                userWlmDao.updateByPrimaryKey(existsUserLikeRecord);
            }


        } else {
            // 当前用户likes model记录
            final List<UserWlmEntity> connectRecords = userWlmDao.queryConnectRecord(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend());
            if (CollectionUtils.isEmpty(connectRecords)) {
                addUserWlm(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend(), Boolean.TRUE);
                addUserWlm(addWlmReq.getUserCodeFriend(), addWlmReq.getUserCode(), Boolean.FALSE);
                return Response.ok();
            }
            // 添加用户Like操作记录
            Predicate<UserWlmEntity> userLikesPredict = o -> o.getUserCode().equals(addWlmReq.getUserCode()) && o.getUserCodeWlm().equals(addWlmReq.getUserCodeFriend());
            final UserWlmEntity userLikesRecord = connectRecords.parallelStream().filter(userLikesPredict).findFirst().orElse(null);
            if (Objects.isNull(userLikesRecord)) {
                addUserWlm(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend(), Boolean.TRUE);
            } else {
                final UserWlmEntity userWlm = connectRecords.get(0);
                userWlm.setFlashchatTime(new Date());
                userWlm.setWlmType(LikeEnum.LIKE_EACH_OTHER.getType());
                userWlm.setFlashchatFlag(Boolean.TRUE);
                if (userWlm.getConnectType() == 0) {
                    userWlm.setConnectType(WLMType.USERFLASHCHAT.getCode());
                }
                userWlmDao.updateByPrimaryKey(userWlm);
            }

            // 添加LikesBack操作
            Predicate<UserWlmEntity> modelLikesBackPredict = o -> o.getUserCode().equals(addWlmReq.getUserCodeFriend()) && o.getUserCodeWlm().equals(addWlmReq.getUserCode());
            final UserWlmEntity likesBackRecord = connectRecords.parallelStream().filter(modelLikesBackPredict).findFirst().orElse(null);
            if (Objects.isNull(likesBackRecord)) {
                addUserWlm(addWlmReq.getUserCodeFriend(), addWlmReq.getUserCode(), Boolean.FALSE);
            }

        }
        return Response.ok();
    }

    private void connectByFlashChatV2(AddWlmReq addWlmReq) {
        // TODO: 2024/1/22  有需要细化的逻辑，例如我发起flashchat但是对方拉黑了我，举报了我
        logger.info("==connectByFlashChatV2==1==, req:{}", JSONObject.toJSONString(addWlmReq));
        final UserEntity userInfo = userDao.selectByUserCode(addWlmReq.getUserCode());
        WLMType matchType = userInfo.getUserType() == UserType.NORMAL_USER.getType() ? WLMType.USERFLASHCHAT : WLMType.CHATTERFLASHCHAT;
        final List<UserWlmEntity> fromRelationRecords = userWlmDao.queryConnectRecord(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend());
        final List<UserWlmEntity> toRelationRecords = userWlmDao.queryConnectRecord(addWlmReq.getUserCodeFriend(), addWlmReq.getUserCode());
        if (CollectionUtils.isEmpty(fromRelationRecords)) {
            UserWlmEntity entity = new UserWlmEntity();
            entity.setUserCode(addWlmReq.getUserCode()).setUserCodeWlm(addWlmReq.getUserCodeFriend()).setWlmType(LikeEnum.LIKE_EACH_OTHER.getType()).setContactTime(new Date()).setConnectType(matchType.getCode());
            entity.setFlashchatTime(new Date());
            entity.setFlashchatFlag(Boolean.TRUE);
            userWlmDao.insert(entity);
        }

        if (CollectionUtils.isEmpty(toRelationRecords)) {
            UserWlmEntity entity = new UserWlmEntity();
            entity.setUserCode(addWlmReq.getUserCodeFriend()).setUserCodeWlm(addWlmReq.getUserCode()).setWlmType(LikeEnum.LIKE_EACH_OTHER.getType()).setContactTime(new Date()).setConnectType(matchType.getCode());
            entity.setFlashchatTime(new Date());
            entity.setFlashchatFlag(Boolean.TRUE);
            userWlmDao.insert(entity);
        }

        updateRecordToFlashchatMatch(matchType, fromRelationRecords);
        updateRecordToFlashchatMatch(matchType, toRelationRecords);
    }

    private void updateRecordToFlashchatMatch(WLMType matchType, List<UserWlmEntity> relations) {
        if (CollectionUtils.isNotEmpty(relations)) {
            UserWlmEntity entity = relations.get(0);
            entity.setFlashchatTime(new Date());
            entity.setWlmType(LikeEnum.LIKE_EACH_OTHER.getType());
            entity.setFlashchatFlag(Boolean.TRUE);
            entity.setConnectType(matchType.getCode());
            userWlmDao.updateByPrimaryKey(entity);
        }
    }

    public Response<AddWlmUserDto> timeFlashChat(AddWlmReq addWlmReq) {

        // 当前用户likes model记录
        final List<UserWlmEntity> connectRecords = userWlmDao.queryConnectRecord(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend());
        if (CollectionUtils.isEmpty(connectRecords)) {
            addFlashUserWlm(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend(), Boolean.TRUE);
            final List<UserWlmEntity> userWlmEntities = userWlmDao.queryConnectRecord(addWlmReq.getUserCodeFriend(), addWlmReq.getUserCode());
            if (CollectionUtils.isEmpty(userWlmEntities)) {
                addFlashUserWlm(addWlmReq.getUserCodeFriend(), addWlmReq.getUserCode(), Boolean.FALSE);
            }
            return Response.ok();
        } else {
            // 添加用户Like操作记录
            Predicate<UserWlmEntity> userLikesPredict = o -> o.getUserCode().equals(addWlmReq.getUserCode()) && o.getUserCodeWlm().equals(addWlmReq.getUserCodeFriend());
            final UserWlmEntity userLikesRecord = connectRecords.parallelStream().filter(userLikesPredict).findFirst().orElse(null);
            if (Objects.isNull(userLikesRecord)) {
                addFlashUserWlm(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend(), Boolean.TRUE);
            }

            // 添加LikesBack操作
            Predicate<UserWlmEntity> modelLikesBackPredict = o -> o.getUserCode().equals(addWlmReq.getUserCodeFriend()) && o.getUserCodeWlm().equals(addWlmReq.getUserCode());
            final UserWlmEntity likesBackRecord = connectRecords.parallelStream().filter(modelLikesBackPredict).findFirst().orElse(null);
            if (Objects.isNull(likesBackRecord)) {
                addFlashUserWlm(addWlmReq.getUserCodeFriend(), addWlmReq.getUserCode(), Boolean.FALSE);
            }
        }
        return Response.ok();
    }

    /**
     * LikesTime只在用户发起like操作时添加数据
     */
    private void addUserWlm(String userCode, String userCodeFriend, boolean addLikesTimeFlag) {
        final UserWlmEntity relation = userWlmDao.getRelation(userCode, userCodeFriend);
        if (relation != null) {
            return;
        }

        UserWlmEntity entity = new UserWlmEntity();
        entity.setUserCode(userCode).setUserCodeWlm(userCodeFriend).setWlmType(LikeEnum.LIKE_EACH_OTHER.getType()).setContactTime(new Date());
        if (addLikesTimeFlag) {
            entity.setFlashchatTime(new Date());
            entity.setFlashchatFlag(Boolean.TRUE);
            entity.setLikesTime(new Date());
            entity.setConnectType(WLMType.USERFLASHCHAT.getCode());
        }

        userWlmDao.insert(entity);
        userWlmLogDao.addWlmLog(entity);
    }

    /**
     * LikesTime只在用户发起like操作时添加数据
     */
    private void addFlashUserWlm(String userCode, String userCodeFriend, boolean addFlashChatTimeFlag) {
        UserWlmEntity entity = new UserWlmEntity();
        entity.setUserCode(userCode).setUserCodeWlm(userCodeFriend).setWlmType(LikeEnum.LIKE_EACH_OTHER.getType()).setContactTime(new Date()).setWlmType(LikeEnum.LIKE_EACH_OTHER.getType());
        if (addFlashChatTimeFlag) {
            entity.setFlashchatTime(new Date());
            entity.setFlashchatFlag(Boolean.TRUE);
            entity.setConnectType(WLMType.USERFLASHCHAT.getCode());
//            entity.setLikesTime(new Date());
        }
        userWlmDao.insert(entity);
        userWlmLogDao.addWlmLog(entity);
    }

    private void pushNewMatchMessage(String userCode, AppEnum appEnum) {
        asyncEventBus.post(buildEvent(userCode, appEnum));
    }

    private Event buildEvent(String userCode, AppEnum appEnum) {
        Map<String, Integer> params = Maps.newHashMap();
        params.put("type", ParameterTypeEnum.MATCHED_PUSH.getId());
        params.put("appCode", appEnum.getAppCode());
        return Event.builder().eventActionEnum(ActionEnum.PUSH_MSG).toUserCode(userCode).app(appEnum).content(JSONObject.toJSONString(params)).build();
    }


    /**
     * 1 拉黑  2取消拉黑 3隐藏  4举报
     *
     * @param addWlmReq 用户码
     */
    @Resource
    AdminReportAuditDao adminReportAuditDao;
    @Resource
    UserChatterMappingDao userChatterMappingDao;

    @Override
    public Response<AddWlmUserDto> doAction(AddWlmReq addWlmReq) {

        // 参数为空， 不作添加操作
        if (Objects.isNull(addWlmReq) || StringUtils.isEmpty(addWlmReq.getUserCode()) || Objects.isNull(addWlmReq.getOpType())) {
            return Response.error("The parameter userCode or opType should not be empty");
        }

        userWlmDao.doAction(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend(), addWlmReq.getOpType(), addWlmReq.getReason());
        userConversationDao.doAction(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend(), addWlmReq.getOpType(), addWlmReq.getReason());

        // 添加举报待审核记录
        if (UserOpActionEnum.REPORT_USER.getType() == addWlmReq.getOpType()) {
            final AdminReportAuditEntity latestRecord = adminReportAuditDao.queryLatestRecord();
            Integer serialNo = 1;
            if (Objects.nonNull(latestRecord)) {
                serialNo = Integer.parseInt(latestRecord.getSerialNo()) + 1;
            }

            final UserEntity user = userDao.selectByUserCode(addWlmReq.getUserCode());
            final UserEntity model = userDao.selectByUserCode(addWlmReq.getUserCodeFriend());
            final List<UserChatterMappingEntity> userChatterMappingEntities = userChatterMappingDao.queryByModelUserCode(addWlmReq.getUserCodeFriend());


            AdminReportAuditEntity entity = new AdminReportAuditEntity();
            entity.setSerialNo(String.valueOf(serialNo));
            entity.setAuditStatus(2);
            entity.setReportedId(model.getUserCode());
            entity.setReportedNickName(model.getNickName());
            entity.setReportId(user.getUserCode());
            entity.setReportNickName(user.getNickName());

            if (CollectionUtils.isNotEmpty(userChatterMappingEntities)) {
                entity.setChatterId(userChatterMappingEntities.get(0).getChatterUserCode());
                entity.setChatterNickName(userChatterMappingEntities.get(0).getChatterNickName());
            }
            if (!StringUtils.isEmpty(addWlmReq.getReason())) {
                final ReportType reportType = ReportType.fromValue(addWlmReq.getReason());
                if (Objects.nonNull(reportType)) {
                    entity.setReportType(reportType.getType());
                }
            } else {
                entity.setReportType(null);
            }
            entity.setReason(addWlmReq.getReason());
            entity.setImages(addWlmReq.getReportImages());

            entity.setReportTime(new Date());
            entity.setSessionFlag(isSendMsg(addWlmReq) ? 1 : 0);
            adminReportAuditDao.insert(entity);

            // 推送消息
            final List<UserEntity> customerServiceLists = userDao.getUsersByUserType(UserType.CUSTOMER_SERVICE.getType());
            if (CollectionUtils.isNotEmpty(customerServiceLists)) {
                pushMessage(customerServiceLists.get(0).getUserCode(), user.getUserCode(), AppEnum.MEBOO);
            }
        }

        return Response.ok(AddWlmUserDto.builder().build());
    }

    private void pushMessage(String fromUseCode, String toUserCode, AppEnum appEnum) {
        pushEventBus.post(buildEvent(fromUseCode, toUserCode, appEnum));
    }

    private Event buildEvent(String fromUseCode, String toUserCode, AppEnum appEnum) {
        Map<String, Integer> params = Maps.newHashMap();
        params.put("type", ParameterTypeEnum.REPORT.getId());
        return Event.builder().eventActionEnum(ActionEnum.PUSH_MSG).fromUserCode(fromUseCode).toUserCode(toUserCode).app(appEnum).content(JSONObject.toJSONString(params)).build();
    }

    private void pushMessage(String fromUseCode, String toUserCode, Integer online, Boolean flashchatFlag, String target) {
        pushEventBus.post(buildEvent(fromUseCode, toUserCode, online, flashchatFlag, target));
    }

    private Event buildEvent(String fromUseCode, String toUserCode, Integer online, Boolean flashchatFlag, String target) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("type", ParameterTypeEnum.PUSH_MODEL_ONLINE.getId());
        params.put("target", target);
        params.put("online", online);
        params.put("flashchatFlag", flashchatFlag);
        return Event.builder().eventActionEnum(ActionEnum.PUSH_MSG).fromUserCode(fromUseCode).toUserCode(toUserCode).app(AppEnum.MEBOO).content(JSONObject.toJSONString(params)).build();
    }

    private boolean isSendMsg(AddWlmReq addWlmReq) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("userCode", addWlmReq.getUserCode());
        params.put("userCodeFriend", addWlmReq.getUserCodeFriend());
        params.put("conversationType", 1);
        final List<UserConversationEntity> userConversationEntities = userConversationDao.queryConversionByUserCode(params);
        if (CollectionUtils.isEmpty(userConversationEntities)) {
            return Boolean.FALSE;
        }
        return !StringUtils.isEmpty(userConversationEntities.get(0).getLatestMsg());

    }


    @Override
    public Response addNewFlag(AddWlmReq addWlmReq) {
        // 获取当前用户主动建立联系的wlm信息
        final List<UserWlmEntity> userWlmEntities = getUserWlmEntities(addWlmReq.getUserCode(), addWlmReq.getUserCodeFriend());
        if (CollectionUtils.isEmpty(userWlmEntities)) {
            return Response.ok();
        }
        final UserWlmEntity wlmEntity = userWlmEntities.get(0);
        wlmEntity.setNewFlag(addWlmReq.getNewFlag());
        userWlmDao.updateByPrimaryKey(wlmEntity);
        return Response.ok();
    }

    @Resource
    UserHomePageRecordDao userHomePageRecordDao;

    private UserWlmEntity addUserWlmEntity(AddWlmReq addWlmReq, boolean matched) {
        UserWlmEntity entity = new UserWlmEntity();

        entity.setUserCode(addWlmReq.getUserCode())
                .setUserCodeWlm(addWlmReq.getUserCodeFriend())
                .setWlmType(addWlmReq.getLikeType())
                .setTagLableType(addWlmReq.getOpType())
                .setReason(addWlmReq.getReason())
                .setNewFlag(NewFlag.NEWS.getType());
        // 设置互相喜欢标识
        //如果发现对方也喜欢我，则需要设置likebacktimes为空
        if (matched) {
            entity.setNewFlag(NewFlag.NEWS.getType());
            entity.setContactTime(new Date());
            entity.setWlmType(LikeEnum.LIKE_EACH_OTHER.getType());
            entity.setConnectType(WLMType.WLM.getCode());
            entity.setLikesTime(new Date());
        }
        if (LikeEnum.LIKE.getType() == addWlmReq.getLikeType()) {
            entity.setLikesTime(new Date());
            entity.setEffectiveDate(DateUtil.offsetDay(DateUtil.date(), userTaskConfig.getWlmLikeEffectiveDays()));
        }
        if (LikeEnum.PASS.getType() == addWlmReq.getLikeType()) {
            entity.setEffectiveDate(DateUtil.offsetDay(DateUtil.date(), userTaskConfig.getWlmPassEffectiveDays()));
//            updateOrSavePreHomepageData(entity.getUserCode(), entity.getUserCodeWlm(), DateUtil.offsetDay(DateUtil.date(), userTaskConfig.getWlmPassEffectiveDays()), LikeEnum.PASS);
        }
        if (LikeEnum.DO_NOT.getType() == addWlmReq.getLikeType()) {
            entity.setEffectiveDate(DateUtil.offsetDay(DateUtil.date(), userTaskConfig.getWlmDisLikeEffectiveDays()))
                    .setDislikeTime(new Date());
//            updateOrSavePreHomepageData(entity.getUserCode(), entity.getUserCodeWlm(), DateUtil.offsetDay(DateUtil.date(), userTaskConfig.getWlmPassEffectiveDays()), LikeEnum.DO_NOT);
        }

        if (Objects.nonNull(addWlmReq.getFlashchatFlag()) && addWlmReq.getFlashchatFlag()) {
            entity.setFlashchatFlag(addWlmReq.getFlashchatFlag());
            entity.setFlashchatTime(new Date());
            entity.setConnectType(WLMType.USERFLASHCHAT.getCode());
        }

        userWlmDao.insert(entity);
        // 增加用户操作日志
        userWlmLogDao.addWlmLog(entity);
        // 增加用户在首页上的操作日志
        addUserHomepageRecord(addWlmReq);

        return entity;
    }

    private void addUserHomepageRecord(AddWlmReq addWlmReq) {
        try {
            UserHomePageRecordEntity userHomePageRecord = new UserHomePageRecordEntity();
            userHomePageRecord.setUserCode(addWlmReq.getUserCode());
            userHomePageRecord.setModelUserCode(addWlmReq.getUserCodeFriend());
            userHomePageRecord.setOperateType(addWlmReq.getLikeType());
            userHomePageRecord.setOnlineStatus(userDao.selectByUserCode(addWlmReq.getUserCodeFriend()).getOnline());
            userHomePageRecordDao.insert(userHomePageRecord);
        } catch (Exception e) {
            logger.error("addUserHomepageRecordFailed, req:{}", JSONObject.toJSONString(addWlmReq), e);
        }
    }

    /**
     * 删除WLM用户
     */
    @Override
    public Response removeWlmUser(String userCode) {
        final Integer removeNum = userWlmDao.removeByUserCode(userCode);
        return Response.ok(removeNum);
    }

    private boolean isMatched(AddWlmReq addWlmReq) {
        // 获取我喜欢的人信息
        final List<UserWlmEntity> whoLikeMeList = getUserWlmEntities(addWlmReq.getUserCodeFriend(), addWlmReq.getUserCode());
        // 是否匹配
        boolean matched = Boolean.FALSE;
        if (LikeEnum.LIKE.getType() == addWlmReq.getLikeType()) {
            matched = whoLikeMeList.stream().anyMatch(o -> o.getWlmType() == LikeEnum.LIKE.getType());
        }
        return matched;
    }


    /**
     * 获取用户关系
     *
     * @param userCode
     * @param userCodeWlm
     * @return
     */
    private List<UserWlmEntity> getUserWlmEntities(String userCode, String userCodeWlm) {
        UserWlmEntity param = new UserWlmEntity();
        param.setUserCode(userCode);
        param.setUserCodeWlm(userCodeWlm);
        return Optional.ofNullable(userWlmDao.selectByWlmUserCode(param)).orElse(Lists.newArrayList());
    }


    /**
     * 功能描述：获取who like me 数量
     *
     * @param userCode 用户码
     * @return
     */
    @Override
    public Response<Integer> wlmNum(String userCode) {
        if (StringUtils.isEmpty(userCode)) {
            return Response.ok();
        }

//        boolean inWhiteList = checkInWhiteList(userCode);
        UserWlmEntity entity = new UserWlmEntity();
        entity.setUserCodeWlm(userCode);
        entity.setDeleted(Boolean.FALSE);
        // 加入白名单账户，WLM只查询model数量
//        entity.setUserType(inWhiteList ? UserType.MODEL.getType() : null);

        return Response.ok(userWlmDao.queryUserRelationNum(entity));
    }

    private boolean checkInWhiteList(String userCode) {
        UserEntity target = userDao.selectByUserCode(userCode);
        if (target == null) {
            // todo 异常处理
            return false;
        }

        Response<Boolean> result = whiteListService.in(target.getAppCode(), target.getUserCode(), target.getMobile(), target.getEmail());
        return result.getData();
    }

    /**
     * 功能描述：获取who like me 列表数据
     *
     * @param userCode 用户码
     * @return
     */
    @Override
    public Response<List<WlmUserDto>> wlmList(String userCode, Page page) {
        if (StringUtils.isEmpty(userCode)) {
            return Response.ok();
        }
        List<UserEntity> wlmUsers;
        if (userCode.equals("1762036137478590464") || userCode.equals("1731596961893679104")) {
            wlmUsers = userDao.selectIOSWlmUsers(page);
        } else {
//            UserEntity currentUser = userDao.selectByUserCode(userCode);
            // 【pp-v1.1.0】12. 流量侧-自然流量>>全局规则>>8. 过滤CM
//            int userType = getFilterUsertypeForWlmList(currentUser);
            wlmUsers = userDao.selectWlmUsers(userCode, null, page);
        }
        if (wlmUsers.isEmpty()) {
            return Response.ok();
        }

        // 查询wlm用户信息
//        final List<String> userCodes = wlmUsers.stream().map(UserWlmEntity::getUserCode).collect(Collectors.toList());
//        final List<UserEntity> userEntities = getUserEntities(userCodes);

        final List<WlmUserDto> collect = wlmUsers.stream().map(o -> getWlmDto(o, userCode)).collect(Collectors.toList());
        return Response.ok(collect);
    }

    /**
     * 是否走非自然流量策略
     * <p>
     * 【pp-v1.1.0】12. 流量侧-自然流量>>全局规则>>8. 过滤CM
     */
    private int getFilterUsertypeForWlmList(UserEntity currentUser) {
        TrafficSourceReq req = TrafficSourceReq.builder()
                .userCode(currentUser.getUserCode())
                .appCode(currentUser.getAppCode())
                .mobile(currentUser.getMobile())
                .email(currentUser.getEmail())
                .build();
        Response<TrafficSourceDto> resp = userTrafficSourceService.getTrafficSource(req);
        if (!resp.isSuccess() || resp.getData() == null) {
            return UserType.ALL.getType();
        }

        if (AppCodeEnum.MEBOO.getAppCode().equals(currentUser.getAppCode()) && resp.getData().getWhiteFlag() == 1) {
            return UserType.MODEL.getType();
        }

        // 过滤CM 如果开关关闭，一律走非自然流量策略；如果开关开启，自然流量走自然流量策略
        if (TrafficSourceEnum.Organic.equals(resp.getData().getTrafficSourceEnum())) {
            return UserType.CHATTER_MODEL.getType();
        }

        return UserType.ALL.getType();
    }

    @Override
    public Response<List<LikeUserDto>> likeList(String userCode, Page page) {
        if (StringUtils.isEmpty(userCode)) {
            return Response.ok();
        }

        // 获取wlm数据
        final List<UserEntity> wlmUsers = userDao.selectLikeUsers(userCode, page);
        if (wlmUsers.isEmpty()) {
            return Response.ok();
        }

        final List<LikeUserDto> collect = wlmUsers.stream().map(o -> getLikeDto(o, userCode)).collect(Collectors.toList());
        return Response.ok(collect);
    }

    @Override
    public Response<Integer> likeCount(String userCode) {
        return Response.ok(userWlmDao.getLikeCount(userCode));
    }


    /**
     * 功能描述：获取新建联用户关系
     *
     * @param userCode 用户码
     * @return
     */
    @Override
    public Response<List<WlmUserDto>> queryLikeEachOtherList(String userCode, Page page) {

//        final List<UserWlmEntity> wlmUserList = userWlmDao.queryLikeEachOtherList(userCode, page);
//
//        final List<String> userCodes = wlmUserList.stream().map(UserWlmEntity::getUserCodeWlm).collect(Collectors.toList());
//        if (CollectionUtils.isEmpty(userCodes)) {
//            return Response.ok();
//        }
//        final List<UserEntity> userEntities = getUserEntities(userCodes);

        Map<String, Object> params = ServiceUtils.getParams();
        params.put("userCode", userCode);
        List<UserEntity> userEntities = userDao.queryMatchUsers(params);

        final List<WlmUserDto> wlmUserDtos = userEntities.stream().map(o -> getWlmDto(o, userCode)).collect(Collectors.toList());

        return Response.ok(wlmUserDtos);
    }

    private List<UserInterestsEntity> getUserInterestsEntities(String userCode) {
        return Optional.ofNullable(userInterestsDao.queryUsers(userCode)).orElse(Lists.newArrayList());
    }


    private List<UserEntity> getUserEntities(List<String> userCodes) {
        Map<String, Object> params = Maps.newConcurrentMap();
        params.put("list", userCodes);
        return Optional.ofNullable(userDao.selectUsers(params)).orElse(Lists.newArrayList());
    }


    /**
     * 获取用户关系
     *
     * @param userCode       用户码
     * @param userCodeFriend 用户码
     * @return
     */
    @Override
    public Response<List<WlmUserDto>> getUserRelation(String userCode, String userCodeFriend) {

        UserWlmEntity entity = new UserWlmEntity();
        entity.setUserCode(userCode);
        entity.setUserCodeWlm(userCodeFriend);
        entity.setDeleted(Boolean.FALSE);
        final List<UserWlmEntity> users = userWlmDao.queryUserRelationByFriendUserCode(entity);

        if (CollectionUtils.isEmpty(users)) {
            return Response.ok();
        }

        final List<WlmUserDto> userWlmDtos = users.stream().map(o -> {
            final WlmUserDto dto = WlmUserDto.builder().build();
            BeanUtils.copyProperties(o, dto);
            return dto;
        }).collect(Collectors.toList());

        return Response.ok(userWlmDtos);
    }

    @Override
    public Integer updateLeaveTime(ConversationOPReq req) {

        Map<String, Object> map = new HashMap<>();
        map.put("userCode", req.getUserCodeFriend());
        map.put("userCodeFriend", req.getModelUserCode());
        map.put("leaveTime", new Date());
        return userConversationDao.updateLeaveTime(map);
    }


    @Override
    public Response addUserUsageBenefits(AddWlmReq addWlmReq) {

        UserEntity userEntity = userDao.selectByUserCode(addWlmReq.getUserCodeFriend());
        if (Objects.isNull(userEntity) || userEntity.getStatus() != UserStatus.ACTIVE.getType()) {
            return Response.error(ResultStatus.USER_NOT_EXIST, "User not found, userCode:{}" + addWlmReq.getUserCodeFriend());
        }
        Map<String, Object> params = ServiceUtils.getParams();
        params.put("userCode", addWlmReq.getUserCode());
        params.put("toUserCode", addWlmReq.getUserCodeFriend());
        params.put("benefitCode", addWlmReq.getLikeType());
        List<UserUsageBenefitsEntity> userUsageBenefitsEntities = usageBenefitsDao.selectByParams(params);
        //如果不存在记录或者新增记录不是Flash_chat则新增
        if (CollUtil.isEmpty(userUsageBenefitsEntities) || addWlmReq.getLikeType() != UserStatus.INIT.getType()) {

            UserUsageBenefitsEntity userUsageBenefitsEntity = new UserUsageBenefitsEntity();
            userUsageBenefitsEntity.setUserCode(addWlmReq.getUserCode());
            userUsageBenefitsEntity.setToUserCode(addWlmReq.getUserCodeFriend());
            userUsageBenefitsEntity.setBenefitCode(addWlmReq.getLikeType());
            userUsageBenefitsEntity.setChatterUserCode(addWlmReq.getChatterUserCode());
            usageBenefitsDao.insert(userUsageBenefitsEntity);
        }

        return Response.ok();
    }

    @Override
    public Response<Integer> getUserMatch(String userCode, String userCodeFriend) {
        int result = 0;
        int count = userWlmDao.getMatchCount(userCode, userCodeFriend);
        int otherCount = userWlmDao.getMatchCount(userCodeFriend, userCode);
        if (count > 0 && otherCount > 0) {
            result = 1;
        }
        return Response.ok(result);
    }

    /**
     * 封装推荐人信息
     *
     * @return
     */
    private RecommendUserDto getRecommendUserDto(UserEntity currentUser, UserEntity model, List<UserInterestsEntity> modelInterests, List<UserAlbumsContentEntity> modelPersonalPhotos, List<UserBehaviorGpsEntity> userBehaviorGpss, Map<String, String> aboutMeMap) {


        // 根据birthday计算用户年龄
        Integer age = ageCalculation(model.getBirthday());

        // 照片处理
        List<ImagesDto> images = null;
        if (CollectionUtils.isNotEmpty(modelPersonalPhotos)) {
            images = modelPersonalPhotos.stream().map(p -> {
                int defaultFlag = 0;
                if (Objects.equals(model.getAvatarUrl(), p.getImageUrl())) {
                    defaultFlag = 1;
                }
                return ImagesDto.builder().imageCode(p.getImageCode()).imageUrl(getImageUrl(p.getImageUrl())).defaultFlag(defaultFlag).build();
            }).sorted(Comparator.comparingInt(ImagesDto::getDefaultFlag).reversed()).collect(Collectors.toList());

        }


        // 兴趣处理
        List<UserInterestDto> interests = null;
        if (CollectionUtils.isNotEmpty(modelInterests)) {
            interests = modelInterests.stream().map(inst -> UserInterestDto.builder().userCode(inst.getUserCode()).interestCode(inst.getInterestCode()).interest(inst.getInterest()).build()).collect(Collectors.toList());
        }


        int nearby = 0;
        if (Objects.nonNull(currentUser.getGpsPrivilege()) && currentUser.getGpsPrivilege() == 1) {
            if (model.getUserType() == UserType.CHATTER_MODEL.getType()) {
                nearby = 1;
            }
        }

        RecommendUserDto recommendUserDto = RecommendUserDto.builder().userType(model.getUserType()).aboutMe(aboutMeMap.get(model.getUserCode())).age(age).interests(interests).lookingFor(model.getLookingFor()).avatarUrl(getImageUrl(model.getAvatarUrl())).gender(model.getGender()).personalPhoto(images).friendUserCode(model.getUserCode()).nickName(model.getNickName()).userCode(currentUser.getUserCode()).online(model.getOnline()).nearby(nearby).build();
//        if (CollectionUtils.isNotEmpty(userBehaviorGpss)) {
//            recommendUserDto.setLat(userBehaviorGpss.get(0).getLat());
//            recommendUserDto.setLng(userBehaviorGpss.get(0).getLng());
//            recommendUserDto.setCity(userBehaviorGpss.get(0).getCity());
//            recommendUserDto.setState(userBehaviorGpss.get(0).getState());
//            recommendUserDto.setStateAbbr(userBehaviorGpss.get(0).getStateAbbr());
//        }
        builderExtendInfo(recommendUserDto, model);
        return recommendUserDto;
    }


    /**
     * 返回扩展信息
     */
    public void builderExtendInfo(RecommendUserDto recommendUser, UserEntity user) {
        String extendInfo = user.getExtendInfo();
        try {
            if (!StringUtils.isEmpty(extendInfo)) {
                ExtendInfoDto extendInfoDto = JSONUtil.toBean(user.getExtendInfo(), ExtendInfoDto.class);
                if (!StringUtils.isEmpty(extendInfoDto.getHeight())) {
                    recommendUser.setHeight(ServiceUtils.feetInchesToCentimeters(extendInfoDto.getHeight()));
                    if (extendInfoDto.getHeight().matches("\\d+'\\d+\"") && !extendInfoDto.isHideHeight()) {
                        recommendUser.setInchHeight(extendInfoDto.getHeight());
                    }
                }
                if (extendInfoDto.getConstellation() != null) {
                    ConstellationEnums zodiac = ConstellationEnums.getZodiacById(extendInfoDto.getConstellation());
                    recommendUser.setConstellation(zodiac.getId());
                    recommendUser.setConstellationName(zodiac.getName());
                    recommendUser.setConstellationIcon(zodiac.getIcon());
                }
                List<Integer> turnOnsList = extendInfoDto.getTurnOnsList();
                if (CollUtil.isNotEmpty(extendInfoDto.getTurnOnsList())) {
                    recommendUser.setTurnOnsListSize(turnOnsList.size());
                }
            }
        } catch (Exception e) {
            logger.error("builderExtendInfo:{}", extendInfo, e);
        }
    }


    private String getImageUrl(String url) {
        return ImagePrefixUtils.getFullImageUrl(url);
    }

    /**
     * 封装WLM信息
     *
     * @param o likeMe用户（喜欢我用户）
     * @return
     */
    public WlmUserDto getWlmDto(UserEntity o, String wlmUserCode) {
        ;

        // 获取userProfile信息
        final UserProfileEntity userProfileEntity = userProfileDao.queryUsersByUserCode(o.getUserCode());

        // 获取是否为新用户标记
        final List<UserWlmEntity> userWlmEntities = getUserWlmEntities(o.getUserCode(), wlmUserCode);
        Integer newFlag = null;
        Date sendWlmTime = null;
        if (CollectionUtils.isNotEmpty(userWlmEntities)) {
            newFlag = userWlmEntities.get(0).getNewFlag();
            sendWlmTime = userWlmEntities.get(0).getSendWlmTime();
        }

        final UserEntity currentUser = userDao.selectByUserCode(wlmUserCode);


        final String avatarUrl = o.getAvatarUrl();
        String imageUrl = ImagePrefixUtils.getFullImageUrl(avatarUrl);

        WlmUserDto wlmUserDto = WlmUserDto.builder().build();
        wlmUserDto.setAboutMe(Objects.isNull(userProfileEntity) ? "" : userProfileEntity.getAboutMe());
        wlmUserDto.setAge(ageCalculation(o.getBirthday()));
        wlmUserDto.setUserCodeFriend(o.getUserCode());
        wlmUserDto.setInterests(getUserInterestDtos(o));
        wlmUserDto.setOnline(o.getOnline());
        wlmUserDto.setOnlineDesc(Objects.isNull(o.getOnline()) ? "" : OnlineStatus.fromType(o.getOnline()).getValue());
        Integer nearby = 0;
        if (Objects.nonNull(currentUser.getGpsPrivilege()) && currentUser.getGpsPrivilege() == 1) {
            if (UserType.CHATTER_MODEL.getType() == o.getUserType()) {
                nearby = 1;
            }
        }
        wlmUserDto.setNearby(nearby);
        wlmUserDto.setNewFlag(newFlag);
        wlmUserDto.setAvatarUrl(imageUrl);
        wlmUserDto.setLookingForDesc(GenderEnum.fromType(o.getLookingFor()).getValue());
        wlmUserDto.setGenderDesc(GenderEnum.fromType(o.getGender()).getValue());
        wlmUserDto.setNickName(o.getNickName());
        wlmUserDto.setUserCode(wlmUserCode);
        wlmUserDto.setWLMTime(sendWlmTime);
        if (!StringUtils.isEmpty(o.getExtendInfo())) {
            ExtendInfoDto extendInfoDto = JSONUtil.toBean(o.getExtendInfo(), ExtendInfoDto.class);
            if (CollUtil.isNotEmpty(extendInfoDto.getTurnOnsList())) {
                wlmUserDto.setTurnOnsListSize(extendInfoDto.getTurnOnsList().size());
            }
        }
        UserBehaviorGpsEntity userBehaviorGpsEntity = userBehaviorGpsDao.getLastGps(o.getUserCode());
        if (userBehaviorGpsEntity != null) {
            wlmUserDto.setCity(userBehaviorGpsEntity.getCity());
            wlmUserDto.setLat(userBehaviorGpsEntity.getLat());
            wlmUserDto.setLng(userBehaviorGpsEntity.getLng());
            wlmUserDto.setState(userBehaviorGpsEntity.getState());
        }

        List<String> messageList = userGreetingCommonContentDao.getGreetingContent("128", 1, o.getAppCode());
        if (!messageList.isEmpty()) {
            wlmUserDto.setGreetingContent(messageList.get(0));
        }

        return wlmUserDto;
    }


    private LikeUserDto getLikeDto(UserEntity o, String wlmUserCode) {

        // 获取userProfile信息
        final UserProfileEntity userProfileEntity = userProfileDao.queryUsersByUserCode(o.getUserCode());

        final UserEntity currentUser = userDao.selectByUserCode(wlmUserCode);

        final String avatarUrl = o.getAvatarUrl();
        String imageUrl = ImagePrefixUtils.getFullImageUrl(avatarUrl);

        LikeUserDto likeUserDto = new LikeUserDto();
        likeUserDto.setAboutMe(Objects.isNull(userProfileEntity) ? "" : userProfileEntity.getAboutMe());
        likeUserDto.setAge(ageCalculation(o.getBirthday()));
        likeUserDto.setUserCode(o.getUserCode());
        likeUserDto.setInterests(getUserInterestDtos(o));
        likeUserDto.setOnline(o.getOnline());
        Integer nearby = 0;
        if (Objects.nonNull(currentUser.getGpsPrivilege()) && currentUser.getGpsPrivilege() == 1) {
            if (UserType.CHATTER_MODEL.getType() == o.getUserType()) {
                nearby = 1;
            }
        }
        likeUserDto.setNearby(nearby);
        likeUserDto.setAvatarUrl(imageUrl);
        likeUserDto.setLookingForDesc(GenderEnum.fromType(o.getLookingFor()).getValue());
        likeUserDto.setNickName(o.getNickName());
        if (!StringUtils.isEmpty(o.getExtendInfo())) {
            ExtendInfoDto extendInfoDto = JSONUtil.toBean(o.getExtendInfo(), ExtendInfoDto.class);
            if (CollUtil.isNotEmpty(extendInfoDto.getTurnOnsList())) {
                likeUserDto.setTurnOnsListSize(extendInfoDto.getTurnOnsList().size());
            }
        }

        return likeUserDto;

    }

    /**
     * 获取用户兴趣
     */
    private List<UserInterestDto> getUserInterestDtos(UserEntity o) {
        // 查询用户兴趣
        final List<UserInterestsEntity> userInterestsEntities = getUserInterestsEntities(o.getUserCode());

        // 处理兴趣
        return userInterestsEntities.stream().map(inst -> UserInterestDto.builder().userCode(inst.getUserCode()).interestCode(inst.getInterestCode()).interest(inst.getInterest()).build()).collect(Collectors.toList());
    }

    /**
     * 年龄计算
     */
    private Integer ageCalculation(Date birthday) {
        Integer age = null;
        if (Objects.nonNull(birthday)) {
            try {
                age = TimeUtils.getAge(birthday);
            } catch (Exception e) {
                logger.error("Age calculation error, birthday:{}", birthday);
            }
        }
        return age;
    }


    private List<UserEntity> queryUsers(String userCode, Integer recordNum, Integer lookingFor) {
        logger.info("==queryUsers 开始 ==,当前用户:{}", userCode);
        UserEntity currentUser = userDao.selectByUserCode(userCode);
        return HomepageTrafficHandler.homepageBaseMap.get(currentUser.getAppCode()).queryUsers(currentUser, recordNum, lookingFor);

    }

    /**
     * 【pp-v1.1.0】自然流量-首页下发仅显示M，随机取Model，排序需要调整
     * 1. 2个女性M，1个男性M，3个资料排序随机，男性M资料使用光后，空位补女性M
     * 2. 不考虑自然流量的性向
     */
    private List<IssueUserPoolEntity> concatIssueUserPoolList(int recordNum, List<IssueUserPoolEntity> maleIssueUserList, List<IssueUserPoolEntity> femaleIssueUserList) {
        if (CollectionUtils.isEmpty(femaleIssueUserList)) {
            return maleIssueUserList;
        }
        int maleCount = 0;
        int femaleCount = 0;
        int maleSize = maleIssueUserList.size();
        int femaleSize = femaleIssueUserList.size();
        int turn = 1;
        List<IssueUserPoolEntity> userCodeEntityList = new ArrayList<>();
        for (int i = 0; i < recordNum; i++) {
            if ((i / 3 == 2 || turn == 0) && maleCount < maleSize) {
                userCodeEntityList.add(maleIssueUserList.get(maleCount));
                maleCount++;
                continue;
            }
            if (i < femaleSize) {
                userCodeEntityList.add(femaleIssueUserList.get(femaleCount));
                femaleCount++;
            } else {
                turn = 0;
            }
        }
        return userCodeEntityList;
    }

    private Integer getUserType(UserType defaultUserType) {
        if (!StringUtils.isEmpty(userTaskConfig.getAppVersion()) && userTaskConfig.getAppVersion().equals("1.0")) {
            return null;
        }
        return defaultUserType.getType();
    }

    /**
     * 获取需要过滤的用户名单，过滤规则：
     * 1. 过滤非model用户
     * 2. 过滤已举报过的用户
     * 3. 过滤已拉黑的用户
     * 4. 过滤已建联的用户（已建联用户包括举报过、拉黑用户），该逻辑位于sql中
     * 5. 过滤72h内pass/dislike的用户
     * 6. 过滤48h内cupid匹配到的用户
     * 7. 过滤48h内like过我的用户
     *
     * @param userCode
     */
    private List<String> queryNeedFilterUserCodes(String userCode, Integer lookFor) {
        List<String> needFilterUserCodes = Lists.newArrayList();
        // 过滤自己
        needFilterUserCodes.add(userCode);

        final List<UserWlmEntity> userRelationEntities = queryRelationUsers(userCode);

        if (CollectionUtils.isNotEmpty(userRelationEntities)) {

            // 过滤已建联用户
            Predicate<UserWlmEntity> wlmPredict = o -> Objects.equals(o.getWlmType(), LikeEnum.LIKE_EACH_OTHER.getType());
            // 过滤黑名单用户
            Predicate<UserWlmEntity> blackPredict = o -> Objects.equals(o.getTagLableType(), UserOpActionEnum.ADD_BLACK_LIST.getType());
            // 过滤已举报用户
            Predicate<UserWlmEntity> reportPredict = o -> Objects.equals(o.getTagLableType(), UserOpActionEnum.REPORT_USER.getType());
            final Predicate<UserWlmEntity> p = wlmPredict.or(blackPredict).or(reportPredict);
            final List<String> filterUsers = userRelationEntities.stream().filter(p).map(UserWlmEntity::getUserCode).collect(Collectors.toList());
            needFilterUserCodes.addAll(filterUsers);
            logger.info("=======被用户：{} 过滤掉的建联、黑名单、举报用户：{}", userCode, filterUsers);

        }
        /**
         // 72h内pass用户
         final Set<String> passUsers = redisClient.sMembers(RedisKey.WLM_PASS, userCode, String.valueOf(lookFor));
         if (CollectionUtils.isNotEmpty(passUsers)) {
         needFilterUserCodes.addAll(passUsers);
         logger.info("=======被用户：{} 72h内pass用户：{}", userCode, passUsers);
         }

         // 72h内dislike用户
         final Set<String> disLikeUsers = redisClient.sMembers(RedisKey.WLM_DISLIKE, userCode, String.valueOf(lookFor));
         if (CollectionUtils.isNotEmpty(disLikeUsers)) {
         needFilterUserCodes.addAll(disLikeUsers);
         logger.info("=======被用户：{} 72h内dislike用户：{}", userCode, disLikeUsers, String.valueOf(lookFor));

         }

         // 过滤48h内cupid匹配到的用户
         final Set<String> matchedUsers = redisClient.sMembers(RedisKey.WLM_MATCHED, userCode, String.valueOf(lookFor));
         if (CollectionUtils.isNotEmpty(matchedUsers)) {
         needFilterUserCodes.addAll(matchedUsers);
         logger.info("=======用户：{} 48h内cupid匹配到的用户：{}", userCode, matchedUsers);

         }

         // 过滤48h内like过我的用户
         final Set<String> likeUsers = redisClient.sMembers(RedisKey.WLM_LIKE, userCode, String.valueOf(lookFor));
         if (CollectionUtils.isNotEmpty(likeUsers)) {
         needFilterUserCodes.addAll(likeUsers);
         logger.info("=======用户：{} 48h内like过我的用户：{}", userCode, likeUsers);
         }
         **/
        return needFilterUserCodes;
    }


    private List<UserWlmEntity> queryRelationUsers(String userCode) {
        Map<String, Object> params = Maps.newConcurrentMap();
        params.put("userCode", userCode);
        params.put("deleted", 0);
        return Optional.ofNullable(userWlmDao.selectByParams(params)).orElse(Collections.emptyList());
    }
}
